package com.example.common;

import com.alibaba.fastjson.JSONObject;
import com.example.factory.HttpRequestServerFactory;
import com.example.factory.HttpRespServerFactory;
import com.example.factory.ServletRequestFactory;
import com.example.factory.ServletResponseFactory;
import com.example.http.HttpRequestServer;
import com.example.http.HttpRespServer;
import com.example.model.FormMulit;
import com.example.proxy.MethodProxy;
import com.example.socket.ServletRequest;
import com.example.socket.ServletResponse;
import com.example.socket.model.MulitiFile;
import com.example.util.ApplicationContent;
import com.example.util.Results;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Classname CommonHandler
 * @Description TODO
 * @Date 2023/4/24 14:54
 * @Created by XiongXiong
 * @Author: X.I.O
 */
public class HttpHandlerModel implements HttpHandler {


    private MethodProxy methodProxy;

    private List<HttpHandlerWeb> httpHandlerWebList;

    private List<HttpHandlerFilter> httpHandlerFilterList;

    public HttpHandlerModel(MethodProxy methodProxy) {
        this.methodProxy = methodProxy;
    }

    @Override
    public void handle(HttpExchange httpExchange) {
        HttpRequestServer httpRequestServer=HttpRequestServerFactory.getHttpRequestServer(httpExchange);
        HttpRespServer httpRespServer= HttpRespServerFactory.getHttpRespServer(httpExchange);

        ServletRequest request= ServletRequestFactory.getServletReqest(httpRequestServer);
        ServletResponse response= ServletResponseFactory.getServletResponse(httpRespServer);

        List<Object> objects=new ArrayList<>();
        addExecuteArgQuery(request,response,objects);
        Object result=null;
        try {
            if(httpHandlerFilterList==null){
                httpHandlerFilterList=ApplicationContent.getObjList(HttpHandlerFilter.class);
            }
            //过滤器执行
            if(!httpHandlerFilterList.isEmpty()){
                for (HttpHandlerFilter httpHandlerFilter : httpHandlerFilterList){
                    boolean falg=httpHandlerFilter.doFilter(request,response);
                    if(!falg){
                        JSONObject obj = Results.error("被系统拦截了1111");
                        if(httpRespServer.isSender()){
                            wirte(httpExchange,obj.toJSONString());
                        }
                        return;
                    }
                }
            }
            if(httpHandlerWebList==null){
                httpHandlerWebList = ApplicationContent.getObjList(HttpHandlerWeb.class);
            }
            //拦截器前置执行
            if(!httpHandlerWebList.isEmpty()){
                for(HttpHandlerWeb httpHandlerWeb:httpHandlerWebList){
                    httpHandlerWeb.beforeHandler(request,response,objects);
                }
            }
            methodProxy.info("execute "+methodProxy.getClazz().getName()+" "+methodProxy.getMethod().getName());
            result=methodProxy.execute(objects.toArray());
            //拦截器后置执行
            if(!httpHandlerWebList.isEmpty()){
                for(HttpHandlerWeb httpHandlerWeb:httpHandlerWebList){
                    result=httpHandlerWeb.afterHandler(request,response,result);
                }
            }
            wirte(httpExchange,result);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 添加执行参数(查询)
     */
    private void addExecuteArgQuery(ServletRequest servletRequest,ServletResponse response,List<Object> objects){
        List<MethodProxy.ArgModel> modelMaps=this.methodProxy.getArgModels();
        if(modelMaps != null){
            for (MethodProxy.ArgModel argModel:modelMaps) {
                String argName =argModel.getName();
                Object val=null;
                if(argModel.getCls().getName().equals(ServletRequest.class.getName())){
                    val=servletRequest;
                }else if(argModel.getCls().getName().equals(ServletResponse.class.getName())){
                    val=servletRequest;
                }else if(argModel.getCls().getName().equals(FormMulit.class.getName())){
                    //处理上传的文件
                    val=executeFormMulit(servletRequest,argModel);
                } else{
                    if(servletRequest.getJson()!=null){
                        JSONObject json=servletRequest.getJson();
                        val=json.get(argName);
                    }
                    if(servletRequest.getFormData()!=null){
                        Map<String,Object> object=servletRequest.getFormData();
                        if(val==null){
                            val=object.get(argName);
                        }
                    }
                    if(servletRequest.getQueryMap()!=null){
                        if(val==null){
                            val=servletRequest.getQueryParamsFirst(argModel.getName());
                        }
                    }
                }
                if(val==null){
                    if(argModel.getDefaultValue()!=null && "".equals(argModel.getDefaultValue())){
                        val=argModel.getDefaultValue();
                    }
                    if(val==null && argModel.isRequired()){
                        //数据最后还是为空
                    }
                }
                objects.add(val);
            }
        }
    }

    /**
     * 处理文件上传
     * @return
     */
    private MulitiFile executeFormMulit(ServletRequest servletRequest, MethodProxy.ArgModel argModel){
        if(servletRequest.getFormData()==null){
            return null;
        }
        Map<String,Object> fromData=servletRequest.getFormData();

        Object value=fromData.get(argModel.getName());
        if(value==null){
            return null;
        }
        if(value instanceof MulitiFile){
            MulitiFile file=(MulitiFile)value;
            return file;
        }
        for (Map.Entry<String, Object> entry : fromData.entrySet()) {
            Object val=entry.getValue();
            if(val instanceof MulitiFile){
                MulitiFile file=(MulitiFile)value;
                return file;
            }
        }
        return null;
    }
    /**
     * 处理文件上传
     * @return
     */
//    private FormMulit executeFormMulit(HttpRequestServer httpRequestServer,MethodProxy.ArgModel argModel){
//        if(httpRequestServer.getMulitMap()==null){
//            return null;
//        }
//        Map<String,FormMulit> map=httpRequestServer.getMulitMap();
//        if(argModel.getName()!=null && !"".equals(argModel.getName())){
//            FormMulit formMulit=map.get(argModel.getName());
//            return formMulit;
//        }
//        for (FormMulit formMulit : map.values()) {
//            return formMulit;
//        }
//        return null;
//    }


    private void wirte(HttpExchange httpExchange,Object obj){
        wirte(httpExchange,obj,200);
    }


    private void wirte(HttpExchange httpExchange,Object obj,int code)  {
        OutputStream os=null;
        try {
            if(httpExchange.getResponseCode()!=-1){
                System.out.println(httpExchange.getResponseCode());
                return;
            }
            String response = JSONObject.toJSONString(obj);
            //发送响应数据
            httpExchange.getResponseHeaders().set("Content-Type", "text/plain;charset=UTF-8");
            httpExchange.sendResponseHeaders(code, response.getBytes(StandardCharsets.UTF_8).length);
            os = httpExchange.getResponseBody();
            os.write(response.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(os != null){
                try {
                    os.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
